﻿<!DOCTYPE HTML>
<html lang="zh">
<head>
<title>Loop Reg - 语法 &amp; 使用 | AutoHotkey v2</title>
<meta name="description" content="The Loop Reg statement retrieves the contents of the specified registry subkey, one item at a time." />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="../static/theme.css" rel="stylesheet" type="text/css" />
<script src="../static/content.js" type="text/javascript"></script>
</head>
<body>

<h1>Loop Reg</h1>

<p>检索指定的注册表子键的内容, 每次一个项目.</p>

<pre class="Syntax"><span class="func">Loop Reg</span> KeyName <span class="optional">, Mode</span></pre>
<h2 id="Parameters">参数</h2>
<dl>

  <dt>KeyName</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
    <p>注册表键的全名.</p>
    <p>必须以 HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CURRENT_USER, HKEY_CLASSES_ROOT 或 HKEY_CURRENT_CONFIG(或这些的缩写, 如 HKLM) 开始. 要访问<a href="#remote">远程注册表</a>, 请在前面加上计算机名和反斜杠, 如本例所示: \\workstation01\HKEY_LOCAL_MACHINE</p>
  </dd>
  
  <dt>Mode</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
    <p>如果为空或省略, 则只包含值且不递归子键. 否则, 指定一个或多个下列字母:</p>
    <ul>
      <li>K = 包含键名.</li>
      <li>V = 包含键值. K 和 V 都被省略时, 默认也包含键值.</li>
      <li>R = 递归子键. 若省略 R, <em>KeyName</em> 下的子键中的键名和键值都不会被包含.</li>
    </ul>
  </dd>

</dl>

<h2 id="Remarks">备注</h2>
<p>当您想对注册表值或子键集合中的项逐个进行操作时, 注册表循环很有用. 值和子键以逆序获取(自下而上), 这样在循环中使用 <a href="RegDelete.htm">RegDelete</a> 和 <a href="RegDeleteKey.htm">RegDeleteKey</a> 不会扰乱循环自身.</p>
<p id="vars">下列变量存在于任何注册表循环中. 如果一个内层注册表循环包含在一个外层注册表循环中, 那么最内层循环的注册表项将具有优先权:</p>
<table class="info">
  <tr>
    <th abbr="Var">变量</th>
    <th abbr="Descr">描述</th>
  </tr>

  <tr>
    <td>A_LoopRegName</td>
    <td>当前获取项的名称, 可以是值名或子键名. 在 Windows 注册表编辑器中, 值名为 "(Default)" 的项如果分配了值, 那么也会获取它的值, 不过此时相应的 A_LoopRegName 将是空的.</td>
  </tr>
  <tr>
    <td>A_LoopRegType</td>
    <td>当前获取项的类型, 可以是下列单词的其中一个: KEY(即当前获取项为子键而不是值), REG_SZ, REG_EXPAND_SZ, REG_MULTI_SZ, REG_DWORD, REG_QWORD, REG_BINARY, REG_LINK, REG_RESOURCE_LIST, REG_FULL_RESOURCE_DESCRIPTOR, REG_RESOURCE_REQUIREMENTS_LIST, REG_DWORD_BIG_ENDIAN(在大多数 Windows 硬件上相当罕见). 如果当前获取项为未知类型, 那么此变量将为空.</td>
  </tr>
  <tr>
    <td>A_LoopRegKey</td>
    <td>包含当前循环项目的键的全名. 对于远程注册表访问, 该值 <strong>不</strong> 包括计算机名称.</td>
  </tr>
  <tr>
    <td>A_LoopRegTimeModified</td>
    <td>当前子键或其任何值最后被修改的时间. 格式为 <a href="FileSetTime.htm">YYYYMMDDHH24MISS</a>. 如果当前检索到的项目不是子键(即 <em>A_LoopRegType</em> 不是单词 KEY), 则该变量为空.</td>
  </tr>
</table>
<p>在注册表循环中使用下列命令时, 可以以一种简化的方式来操作当前获取项:</p>
<table class="info">
  <tr>
    <th style="min-width: 11em;">语法</th>
    <th abbr="Descr">描述</th>
  </tr>
  <tr>
    <td><code>Value := <a href="RegRead.htm">RegRead</a>()</code></td>
    <td>读取当前项. 如果当前项为键, 则抛出异常.</td>
  </tr>
  <tr>
    <td><code><a href="RegWrite.htm">RegWrite</a> Value</code><br><code><a href="RegWrite.htm">RegWrite</a></code></td>
    <td>写入到当前项. 如果省略 <em>Value</em>, 根据不同的类型当前项可能被置为 0 或空. 如果当前项为键, 则抛出异常, 并且注册表不会被修改.</td>
  </tr>
  <tr>
    <td><code><a href="RegDelete.htm">RegDelete</a></code></td>
    <td>如果当前项目是值, 则删除当前项目. 如果当前项目是键, 则会删除其默认值.</td>
  </tr>
  <tr>
    <td><code><a href="RegDeleteKey.htm">RegDeleteKey</a></code></td>
    <td>如果当前项目是键, 则删除当前项目. 如果当前项目是一个值, 则 <em>包含</em> 该值的键将被删除, 包括所有子键和值.</td>
  </tr>
  <tr>
    <td><code>RegCreateKey</code></td>
    <td>如上面 RegDeleteKey 所示的目标键. 如果该键在循环中被删除, 则可以使用 RegCreateKey 重新创建该键. 否则, 仅仅验证脚本是否具有对键的写访问权.</td>
  </tr>
</table>
<p id="remote">访问远程注册表时(通过上面描述的 <em>KeyName</em> 参数), 需要注意以下事项:</p>
<ul>
  <li>目标机器上必须正在运行远程注册表服务.</li>
  <li>如果您和目标计算机不在相同的域或者本地或远程用户名缺乏足够的权限(然而, 请参阅下文了解可能的解决方法) 时, 访问远程注册表可能失败.</li>
  <li>在尝试访问远程注册表之前, 根据您的用户名所在的域, 工作组和/或权限, 您可能必须连接到共享设备, 例如通过映射驱动器. 建立这样的连接 -- 使用拥有访问或编辑注册表权限的远程用户名和密码 -- 也许可以顺带启用远程注册表访问</li>
  <li>如果您已经作为另一个用户连接到目标计算机(例如, 通过 Guest 用户映射驱动器), 您可能必须终止这个连接, 以允许远程注册表功能使用您当前登录的用户名重新连接和认证.</li>
</ul>
<p id="otb">可以选择使用 One True Brace(OTB) 样式, 它允许左大括号出现在同一行而不是下面. 例如: <code>Loop Reg "HKLM\Software\AutoHotkey", "V" {</code>.</p>
<p>请参阅 <a href="Loop.htm">Loop</a> 了解关于<a href="Block.htm">区块</a>, <a href="Break.htm">Break</a>, <a href="Continue.htm">Continue</a> 和 A_Index 变量(其存在于各种类型的循环中) 的相关信息.</p>
<p>循环后面可以有一个可选的 <a href="Else.htm">Else</a> 语句, 如果没有找到指定类型的注册表项(即循环的迭代次数为零), 则执行 Else 语句.</p>

<h2 id="Related">相关</h2>
<p><a href="Loop.htm">Loop</a>, <a href="Break.htm">Break</a>, <a href="Continue.htm">Continue</a>, <a href="Block.htm">区块</a>, <a href="RegRead.htm">RegRead</a>, <a href="RegWrite.htm">RegWrite</a>, <a href="RegDelete.htm">RegDelete</a>, <a href="RegDeleteKey.htm">RegDeleteKey</a>, <a href="SetRegView.htm">SetRegView</a></p>

<h2 id="Examples">示例</h2>
<div class="ex" id="ExRegDelete">
<p><a class="ex_number" href="#ExRegDelete"></a> 删除用户输入的 Internet Explorer 的 URL 历史.</p>
<pre>Loop Reg, "HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\TypedURLs"
    RegDelete</pre>
</div>

<div class="ex" id="ExBasic">
<p><a class="ex_number" href="#ExBasic"></a> 有效的测试脚本.</p>
<pre>Loop Reg, "HKCU\Software\Microsoft\Windows", "R KV"  <em>; 递归检索键和值.</em>
{
    if A_LoopRegType = "key"
        value := ""
    else
    {
        try
            value := RegRead()
        catch
            value := "*error*"
    }
    Result := MsgBox(A_LoopRegName " = " value " (" A_LoopRegType ")`n`nContinue?",, "y/n")
}
Until Result = "No"</pre>
</div>

<div class="ex" id="ExRegSearch">
<p><a class="ex_number" href="#ExRegSearch"></a> 用于在整个注册表中递归搜索特定值.</p>
<pre>
RegSearch("Notepad")

RegSearch(Target)
{
    Loop Reg, "HKEY_LOCAL_MACHINE", "KVR"
    {
        if !CheckThisRegItem()  <em>; 这里告知我们要停止搜索.</em>
            return
    }
    Loop Reg, "HKEY_USERS", "KVR"
    {
        if !CheckThisRegItem()  <em>; 这里告知我们要停止搜索.</em>
            return
    }
    Loop Reg, "HKEY_CURRENT_CONFIG", "KVR"
    {
        if !CheckThisRegItem()  <em>; 这里告知我们要停止搜索.</em>
            return
    }
    <em>; 请注意: 我认为如果已经搜索了 HKEY_USERS, 那么可以不必搜索 HKEY_CURRENT_USER.
    ; 同样地, HKEY_CLASSES_ROOT  提供了
    ; HKEY_LOCAL_MACHINE 和 HKEY_CURRENT_USER 键的集合视图, 所以完全搜索这三个键是没有必要的.</em>

    CheckThisRegItem()
    {
        if A_LoopRegType = "KEY"  <em>; 如果您也想检查键名, 那么移除这两行.</em>
            return true
        try
            RegValue := RegRead()
        catch
            return true
        if InStr(RegValue, Target)
        {
            Result := MsgBox(
            (
            "The following match was found:
            " A_LoopRegKey "\" A_LoopRegName "
            Value = " RegValue "
            
            Continue?"
            ),, "y/n")
            if Result = "No"
                return false  <em>; 告知我们的调用者停止搜索.</em>
        }
        return true
    }
}
</pre>
</div>

</body>
</html>